<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>pg_locks</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="view-pg-indexes.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="catalogs.html">快退</a></td><td width="60%" align="center" valign="bottom">章43. 系统表</td><td width="10%" align="right" valign="top"><a href="catalogs.html">快进</a></td><td width="10%" align="right" valign="top"><a href="view-pg-prepared-statements.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="VIEW-PG-LOCKS">43.39. <tt class="STRUCTNAME">pg_locks</tt></a></h1><a name="AEN65636"></a>
<p><tt class="STRUCTNAME">pg_locks</tt> 提供有关在数据库服务器中由打开的事务持有的锁的信息。参阅<a href="mvcc.html">章12</a>获取有关锁的更多的讨论。</p>
<p><tt class="STRUCTNAME">pg_locks</tt> 对每个活跃的可锁定对象、请求的锁模式、以及相关的事务保存一行。因此，如果多个事务持有或者等待对同一个对象的锁，那么同一个可锁定的对象可能出现多次。不过，一个目前没有锁在其上的对象将肯定不会出现。</p>
<p>有好几种不同的可锁定对象：一个关系(也就是一个表)、关系中独立页面、关系中独立的行、一个事务 ID 、以及一般的数据库对象(用类别 OID 和对象 OID 标识，表示方法和 <tt class="STRUCTNAME">pg_description</tt> 或 <tt class="STRUCTNAME">pg_depend</tt>一样)还有，扩展一个关系的权限也是用一种独立的可锁定对象表示的。</p>
<div class="TABLE"><a name="AEN65646"></a>
<p><b>表43-39. <tt class="STRUCTNAME">pg_locks</tt> 字段</b></p>
<table border="1" class="CALSTABLE"><col><col><col><col>
<thead>
<tr><th>名字</th><th>类型</th><th>引用</th><th>描述</th></tr>
</thead>
<tbody>
<tr><td><tt class="STRUCTFIELD">locktype</tt></td><td><tt class="TYPE">text</tt></td><td>&nbsp;</td><td>可锁定对象的类型：<tt class="LITERAL">relation</tt>, <tt class="LITERAL">extend</tt>, <tt class="LITERAL">page</tt>, <tt class="LITERAL">tuple</tt>, <tt class="LITERAL">transactionid</tt>, <tt class="LITERAL">object</tt>, <tt class="LITERAL">userlock</tt>, <tt class="LITERAL">advisory</tt> 之一</td></tr>
<tr><td><tt class="STRUCTFIELD">database</tt></td><td><tt class="TYPE">oid</tt></td><td><tt class="LITERAL"><a href="catalog-pg-database.html"><tt class="STRUCTNAME">pg_database</tt></a>.oid</tt></td><td>对象所在的数据库的 OID ，如果对象是共享对象，那么就是零，如果对象是一个事务 ID ，就是 NULL 。</td></tr>
<tr><td><tt class="STRUCTFIELD">relation</tt></td><td><tt class="TYPE">oid</tt></td><td><tt class="LITERAL"><a href="catalog-pg-class.html"><tt class="STRUCTNAME">pg_class</tt></a>.oid</tt></td><td>关系的 OID ，如果对象不是关系，也不是关系的一部分，则为 NULL</td></tr>
<tr><td><tt class="STRUCTFIELD">page</tt></td><td><tt class="TYPE">integer</tt></td><td>&nbsp;</td><td>关系内部的页面编号，如果对象不是行页不是关系页，则为 NULL</td></tr>
<tr><td><tt class="STRUCTFIELD">tuple</tt></td><td><tt class="TYPE">smallint</tt></td><td>&nbsp;</td><td>页面里面的行编号，如果对象不是行，则为 NULL</td></tr>
<tr><td><tt class="STRUCTFIELD">transactionid</tt></td><td><tt class="TYPE">xid</tt></td><td>&nbsp;</td><td>事务的 ID ，如果对象不是事务 ID ，就是 NULL</td></tr>
<tr><td><tt class="STRUCTFIELD">classid</tt></td><td><tt class="TYPE">oid</tt></td><td><tt class="LITERAL"><a href="catalog-pg-class.html"><tt class="STRUCTNAME">pg_class</tt></a>.oid</tt></td><td>包含该对象的系统表的 OID ，如果对象不是普通数据库对象，则为 NULL</td></tr>
<tr><td><tt class="STRUCTFIELD">objid</tt></td><td><tt class="TYPE">oid</tt></td><td>任意 oid 属性</td><td>对象在其系统表内的 OID ，如果对象不是普通数据库对象，则为 NULL</td></tr>
<tr><td><tt class="STRUCTFIELD">objsubid</tt></td><td><tt class="TYPE">smallint</tt></td><td>&nbsp;</td><td>对于表的一个字段，这是字段编号(<tt class="STRUCTFIELD">classid</tt> 和 <tt class="STRUCTFIELD">objid</tt> 指向表自身)。对于其它对象类型，这个字段是零。如果这个对象不是普通数据库对象，则为 NULL</td></tr>
<tr><td><tt class="STRUCTFIELD">transaction</tt></td><td><tt class="TYPE">xid</tt></td><td>&nbsp;</td><td>持有此锁或者在等待此锁的事务的 ID </td></tr>
<tr><td><tt class="STRUCTFIELD">pid</tt></td><td><tt class="TYPE">integer</tt></td><td>&nbsp;</td><td>持有或者等待这个锁的服务器进程的进程 ID 。如果锁是被一个预备事务持有的，那么为 NULL</td></tr>
<tr><td><tt class="STRUCTFIELD">mode</tt></td><td><tt class="TYPE">text</tt></td><td>&nbsp;</td><td>这个进程持有的或者是期望的锁模式(参阅<a href="explicit-locking.html#LOCKING-TABLES">节12.3.1</a>)</td></tr>
<tr><td><tt class="STRUCTFIELD">granted</tt></td><td><tt class="TYPE">boolean</tt></td><td>&nbsp;</td><td>如果持有锁，为真，如果等待锁，为假</td></tr>
</tbody>
</table>
</div>
<p><tt class="STRUCTFIELD">granted</tt> 为真时表明指定事务持有一个锁。为假则表明该事务当前等待使用这个锁，这就暗示着某个其它的事务正在同样的可锁定对象上持有冲突的锁模式。等待的会话将一直睡眠，直到另外一个锁释放(或者侦测到一个死锁条件)。一个事务一次最多等待一个锁。</p>
<p>每个事务都在它持续的时间里在他自己的事务 ID 上持有一个排他锁。如果一个事务认为它必须等待另外一个事务，它会以企图在另外一个事务 ID 上获取共享锁的方式实现之。这个锁只有在另外一个事务终止并且释放它的锁的前提下才能成功。</p>
<p>尽管行是一种可以锁定的对象，但是有关行级别锁的信息是存储在磁盘上的，而不是在内存里，因此，行级别的锁通常不会出现在这个视图里。如果一个事务在等待一个行级别的锁，那么它通常会在这个视图里以等待当前持有该行锁的事务 ID 的方式出现。</p>
<p>建议锁可以在由单独一个 <tt class="TYPE">bigint</tt> 值或两个<tt class="TYPE">integer</tt>值组成的键上获得。一个 <tt class="TYPE">bigint</tt> 键的高/低位部分分别在 <tt class="STRUCTFIELD">classid</tt> 和 <tt class="STRUCTFIELD">objid</tt> 字段中显示，并且 <tt class="STRUCTFIELD">objsubid</tt> 等于 1 。<tt class="TYPE">integer</tt> 组成的键前半部分在 <tt class="STRUCTFIELD">classid</tt> 字段中显示、后半部分在 <tt class="STRUCTFIELD">objid</tt> 字段中显示，并且 <tt class="STRUCTFIELD">objsubid</tt> 等于 2 。键的实际含义取决于用户的定义。建议锁是针对单个数据库的，因此 <tt class="STRUCTFIELD">database</tt> 字段对于建议锁就显得很有意义了。</p>
<p>在访问 <tt class="STRUCTNAME">pg_locks</tt> 视图的时候，内部的锁管理器数据结构会暂时被锁住，然后制作一份这个视图的拷贝用于显示。这样就保证了视图生成一套连贯的结果，它不会不必要地过分阻塞普通的锁管理器。但是如果这个视图访问得太频繁，肯定是会对数据库性能有些影响的。</p>
<p><tt class="STRUCTNAME">pg_locks</tt> 提供了一个数据库集群里的所有的锁的全局视图，而不仅仅那些和当前数据库相关的。尽管它的 <tt class="STRUCTFIELD">relation</tt> 字段可以和 <tt class="STRUCTNAME">pg_class</tt>.<tt class="STRUCTFIELD">oid</tt> 连接起来以标识被锁住的关系，但是这个方法目前只能对在当前数据库里的关系有用(那些 <tt class="STRUCTFIELD">database</tt> 字段是当前数据库的 OID 或者零的数据库)。</p>
<p>如果你打开了统计收集器，<tt class="STRUCTFIELD">pid</tt> 字段可以可以和 <tt class="STRUCTNAME">pg_stat_activity</tt> 视图的 <tt class="STRUCTFIELD">procpid</tt> 字段连接起来获取持有或者等待持有这个锁的会话的更多信息。同样，如果你使用预备事务，可以把 <tt class="STRUCTFIELD">transaction</tt> 字段和 <tt class="STRUCTNAME">pg_prepared_xacts</tt> 视图的 <tt class="STRUCTFIELD">transaction</tt> 字段连接起来获取持有锁的那个预备事务的更多信息。一个预备事务不能等待任何锁，但是在运行的时候，它继续持有它已经请求到的锁。</p>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="view-pg-indexes.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="view-pg-prepared-statements.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top"><tt class="STRUCTNAME">pg_indexes</tt></td><td width="34%" align="center" valign="top"><a href="catalogs.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top"><tt class="STRUCTNAME">pg_prepared_statements</tt></td></tr>
</table>
</div>
</body></html>